package com.aliyun.service.impl;

import com.aliyun.pojo.oss.AliyunOss;
import com.aliyun.pojo.AliyunAuthentication;
import com.aliyun.pojo.sms.AliyunSms;
import com.aliyun.pojo.AliyunStsAuthorization;
import com.aliyun.properties.AliyunProperties;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.auth.sts.AssumeRoleRequest;
import com.aliyuncs.auth.sts.AssumeRoleResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;

import lombok.extern.slf4j.Slf4j;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 阿里云认证授权服务
 */
@Slf4j
public class AliyunCredentialsService {

    private final AliyunProperties aliyunProperties;

    private static final Map<String, AliyunAuthentication> authorityMap = new HashMap<>();

    public AliyunCredentialsService(AliyunProperties aliyunProperties) {
        this.aliyunProperties = aliyunProperties;
    }

    public AliyunSms getSms(){
        return aliyunProperties.getSms();
    }

    public AliyunOss getOss(){
        return aliyunProperties.getOss();
    }

    /**
     * 获取Sts Token 临时访问凭证
     */
    public AliyunAuthentication tryGetStsAuthorization(AliyunStsAuthorization aliyunStsAuthorization){
        // Sts 服务接入点
        String endpoint = aliyunStsAuthorization.getEndpoint();
        // RAM角色的资源描述符
        String role_arn = aliyunStsAuthorization.getRamRoleArn();
        // RAM用户的AccessKeyId
        String access_key_id = aliyunStsAuthorization.getAccessKeyId();
        // RAM用户的AccessKeySecret
        String access_key_secret = aliyunStsAuthorization.getAccessKeySecret();
        // 临时访问凭证的有效时间，单位为秒
        Long durationSeconds = aliyunStsAuthorization.getDurationSeconds();
        // 发起STS请求所在的地域。建议保留默认值，默认值为空字符串（""）。
        String regionId = "";
        // 自定义角色会话名称，用来区分不同的令牌
        String roleSessionName = UUID.randomUUID().toString();
        // 添加endpoint
        DefaultProfile.addEndpoint(regionId, "Sts", endpoint);
        // 构造default profile
        DefaultProfile profile = DefaultProfile.getProfile(regionId, access_key_id, access_key_secret);
        // 构造client。
        DefaultAcsClient acsClient = new DefaultAcsClient(profile);
        // 获取临时凭证请求对象
        AssumeRoleRequest request = new AssumeRoleRequest();
        request.setRoleArn(role_arn); // 角色的资源描述符
        request.setRoleSessionName(roleSessionName);  // 自定义角色会话名称
        request.setPolicy(null);  // 默认为空，表示不指定临时凭证的权限策略。 临时访问凭证将获得角色拥有的所有权限。
        request.setDurationSeconds(durationSeconds);    // 设置临时访问凭证的有效时间
        // 发起请求 并返回结果
        try {
            AssumeRoleResponse response = acsClient.getAcsResponse(request);
            // 获取临时访问凭证
            AssumeRoleResponse.Credentials credentials = response.getCredentials();
            String expiration = credentials.getExpiration();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
            sdf.setTimeZone(TimeZone.getTimeZone("UTC")); // 设置时区为 UTC
            Date date = sdf.parse(expiration);
            return new AliyunAuthentication(credentials.getSecurityToken(), credentials.getAccessKeySecret(), credentials.getAccessKeyId(), date);
        } catch (ClientException e) {
            log.error("获取临时凭证失败 状态码: {} 错误原因：{}",e.getErrCode(),e.getErrMsg());
            return null;
        } catch (ParseException e) {
            log.error("解析日期对象失败 错误原因：{}",e.getMessage());
            return null;
        }
    }


}
